package com.hjm.project.system.db.controller;

import com.hjm.common.utils.Aes;
import com.hjm.common.utils.StringUtils;
import com.hjm.framework.aspectj.lang.annotation.Log;
import com.hjm.framework.aspectj.lang.enums.BusinessType;
import com.hjm.framework.web.controller.BaseController;
import com.hjm.framework.web.domain.AjaxResult;
import com.hjm.framework.web.page.TableDataInfo;
import com.hjm.project.ShopOrder.ShopOrder.utils.JsonUtils;
import com.hjm.project.system.db.domain.Db;
import com.hjm.project.system.db.service.DbService;
import com.hjm.project.system.db.utils.UserUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 参数配置 信息操作处理
 */
@Controller
@RequestMapping("/db/config")
public class DbController extends BaseController
{
    private String prefix = "system/db";

    /**
     *桌面密码
     */
    public static final String PWD_HOME = "bc79c0cf31ff6956f00b2bab7e763931";

    /**
     *一级密码
     */
    public static final String PWD = "c6579529cb3180be86ca959e4f52ff65";
    /**
     *二级密码
     */
    public static final String PWD1 = "0735b5a0e4f7313d8d2e3453181ac505";

    /**
     *是否需要进行二级验证
     */
    public static final String TWO = "0";

    /**
     *桌面密码
     */
    public static final String ONE = "0";

    /**
     *执行类型
     */
    private static final String SELECT = "1";
    private static final String UPDATE = "2";
    private static final String INSERT = "3";
    private static final String DELETE = "4";
    private static final String OTHER  = "6";
    private static final String ALERT = "5";


    /**
     *更改字段名称
     */
    private static final String ALERT_C = "1";

    /**
     *更改字段数据类型
     */
    private static final String ALERT_M = "2";

    /**
     *更改字段数据类型
     */
    private static final String ALERT_L = "3";


    private static List<String> userInfo = new ArrayList<>();

    @Autowired
    private DbService dbService;

    @RequiresPermissions("db:config:view")
    @GetMapping()
    public String config() {
        return prefix + "/dbList";
    }


    /**
     *执行SQL
     */
    @RequiresPermissions("db:config:perform")
    @GetMapping("/perform")
    public String perform(@RequestParam Map map,ModelMap view) {
        view.put("pwd",map.get("pwd"));
        view.put("pwdHome",map.get("pwdHome"));
        return prefix + "/perform";
    }




    @RequiresPermissions("db:edit:view")
    @GetMapping("/edit")
    public String edit(@RequestParam String tableName,ModelMap modelMap) {
        Map<String, Object> tableDetail = dbService.selectTableOne(tableName);
        modelMap.put("tableDetail",tableDetail);
        return prefix + "/edit";
    }


    /**
     * 表结构页面
     * @Param [tableName, modelMap]
     * @Return java.lang.String
     */
    @RequiresPermissions("db:find:view")
    @GetMapping("/find")
    public String find(@RequestParam String TABLE_NAME,ModelMap modelMap) {
        modelMap.put("table_name",TABLE_NAME);
        return prefix + "/find";
    }

    /**
     * 前往可编辑表结构页面
     * @Param [tableName, modelMap]
     * @Return java.lang.String
     */
    @RequiresPermissions("db:find:editView")
    @GetMapping("/editView")
    public String editView(@RequestParam String TABLE_NAME,ModelMap modelMap) {
        modelMap.put("table_name",TABLE_NAME);
        return prefix + "/editView";
    }

    /**
     * 前往添加列页面
     * @Param [tableName, modelMap]
     * @Return java.lang.String
     */
    @RequiresPermissions("db:find:add")
    @GetMapping("/add")
    public String add(@RequestParam String TABLE_NAME,ModelMap modelMap) {
        modelMap.put("table_name",TABLE_NAME);
        return prefix + "/edit";
    }

    /**
     * 获取表结构数据
     * @Param [map]
     * @Return com.hjm.framework.web.page.TableDataInfo
     */
    @RequiresPermissions("db:find:viewList")
    @PostMapping("/findViewList")
    @ResponseBody
    public TableDataInfo findViewList(Db db) {
        List<Map<String, String>> tableDetail = dbService.selectTableStructure(db);
        return getDataTable(tableDetail);
    }




    /**
     * 获取所有表
     */
    @RequiresPermissions("db:config:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Db db) {
        if (!StringUtils.isEmpty(db.getPwdHome()) && UserUtils.getInfo(Aes.aesDecrypt(db.getPwdHome())).equals(PWD_HOME)) {
            List<Map<String, String>> maps = dbService.selectTableList(db);
            return getDataTable(maps);
        } else {
            return getDataTable(new ArrayList<Map<String, String>>());
        }
    }


    /**
     * 验证桌面口令
     * @Param [param]
     * @Return java.lang.Object
     */
    @RequiresPermissions("db:config:passwordHome")
    @PostMapping("/passwordHome")
    @ResponseBody
    public Object passwordHome(@RequestParam Map param) throws Exception {
        //请求包
        Object key = param.get("key");
         if (key == null || key.equals("")) {
            return error("参数错误");
        }
        Map<String, Object> data = JsonUtils.jsonToMap(Aes.aesDecrypt(key.toString()));
        //桌面密码
        String pwd = Aes.aesDecrypt(String.valueOf(data.get("pwdHome")));
        //验证桌面密码
        if (!PWD_HOME.equals(UserUtils.getInfo(pwd))) {
            return error("请输入正确口令");
        }

        return success("验证成功");
    }



    /**
     * DB管理的密码
     */
    @RequiresPermissions("db:config:pwd")
    @PostMapping("/pwd")
    @ResponseBody
    @Log(title = "验证口令",businessType = BusinessType.OTHER)
    public Object password(@RequestParam Map param) throws Exception {
        try{
            //请求包
            Object key = param.get("key");
            if (key == null || key.equals("")) {
                return error("参数错误");
            }

            Map<String, Object> data = JsonUtils.jsonToMap(Aes.aesDecrypt(key.toString()));

            //一级密码
            String pwd = Aes.aesDecrypt(String.valueOf(data.get("pwd")));
            //二级密码(数据加密长度必须是16位数的倍数异常)
            String pwd1 = "";
            if (data.get("pwd1") != null && !data.get("pwd1").equals("")) {
                pwd1 = Aes.aesDecrypt(String.valueOf(data.get("pwd1")));
            }
            //桌面密码
            String pwdHome = "";
            if (data.get("pwdHome") != null && !data.get("pwdHome").equals("") && data.get("pwdHome").toString().length() >= 6) {
                pwdHome = Aes.aesDecrypt(String.valueOf(data.get("pwdHome")));
            } else {
                return error("验证失败");
            }


            //是否需要验证二级密码标识
            String two = data.get("two") == null ? "1" : data.get("two").toString();
            String pwdHomeStatus = data.get("one") == null ? "1" : data.get("one").toString();

            // 1 + 2 验证
            if (PWD_HOME.equals(UserUtils.getInfo(pwdHome)) && PWD.equals(UserUtils.getInfo(pwd)) && "1".equals(two)) {
                return success("验证成功");
            }

            // 1 + 2 + 3验证(需通过一级密码验证和首页验证)
            if (PWD_HOME.equals(UserUtils.getInfo(pwdHome)) && PWD1.equals(UserUtils.getInfo(pwd1)) && PWD.equals(UserUtils.getInfo(pwd)) && TWO.equals(two) && ONE.equals(pwdHomeStatus) ) {
                return success("验证成功");
            }
        }catch (Exception e){
            return error("验证失败");
        }
        return error("请输入正确口令");
    }



    /**
     * 返回执行结果
     */
    @RequiresPermissions("db:config:performBody")
    @PostMapping("/performBody")
    @ResponseBody
    public Object performList(@RequestParam Map param) {
       try{
           //请求参数
           if (param.get("key") == null || StringUtils.isEmpty(param.get("key").toString())) {
                return error("请求参数错误");
           }
           String content =  Aes.aesDecrypt(String.valueOf(param.get("key")));
           Map<String, Object> data = JsonUtils.jsonToMap(content);
           String str = data.get("content").toString().replaceAll("\r|\n", "");
           /*if (str.substring(str.length()-1,str.length()).indexOf("`") == -1) {
               return error("内容验证失败");
           }
           str = str.substring(0, str.length()-1);*/
           //密码
           String pwd = String.valueOf(data.get("pwd"));
           if (StringUtils.isEmpty(pwd)) {
                return error("密码失效,请重新验证");
           }
           //解密
           String pwdEncrypt = Aes.aesDecrypt(pwd);
           if (!PWD.equals(UserUtils.getInfo(pwdEncrypt))) {
               return error("密码错误,请重新验证");
           }

           //执行语句类型
           String type = data.get("type").toString();
           if (StringUtils.isEmpty(type)) {
               return error("请选择类型");
           }

           if (!OTHER.equals(type)){
           //查询
           String sql = str.toLowerCase();
           if (SELECT.equals(type)) {
               if (!sql.contains("select") && !sql.contains("from")) {
                   return error("请重新选择SQL类型");
               }
               String result = dbService.performResult(str);
               return getData(result);
           }

           //更新
           if (UPDATE.equals(type)) {
               if (!sql.contains("update") || !sql.contains("set")) {
                   return error("请输入正确的SQL");
               }
           } else if (DELETE.equals(type)){
               if (!sql.contains("delete") || !sql.contains("from")) {
                   return error("请输入正确的SQL");
               }
           } else if (INSERT.equals(type)){
               if (!sql.contains("insert into") || !sql.contains("values")) {
                   return error("请输入正确的SQL");
               }
           }
           }
           dbService.saveOrUpdate(str, type);
           return success("操作成功");
       }catch (Exception e){
           //错误代码
            return error(e.getCause().getMessage());
        }
    }



    /**
     * 更新字段
     */
    @RequiresPermissions("db:config:updateColumn")
    @PostMapping("/updateColumn")
    @ResponseBody
    public AjaxResult updateColumn(@RequestParam Map param) throws Exception {

        try {
            String content =  Aes.aesDecrypt(String.valueOf(param.get("key")));
            if (StringUtils.isEmpty(content)) {
                return AjaxResult.error("参数错误");
            }
            //修改参数
            Map<String, Object> params = JsonUtils.jsonToMap(content);
            if (StringUtils.isEmpty(String.valueOf(params.get("field")))) {
                return AjaxResult.error("字段不能为空");
            } else if (StringUtils.isEmpty(String.valueOf(params.get("tableName")))) {
                return AjaxResult.error("表明不能为空");
            } else if (StringUtils.isEmpty(String.valueOf(params.get("value")))) {
                return AjaxResult.error("新值不能为空");
            } else if (StringUtils.isEmpty(String.valueOf(params.get("oldValue")))) {
                return AjaxResult.error("旧值不能为空");
            } else if (StringUtils.isEmpty(String.valueOf(params.get("column")))) {
                return AjaxResult.error("列明不能为空");
            }
            int i = dbService.updateColumn(params);
            return toAjax(i);
        }catch (Exception e){
            return AjaxResult.error("更改失败"+e.getMessage());
        }
    }


    /**
     * 添加一个字段
     */
    @RequiresPermissions("db:config:addColumn")
    @PostMapping("/addColumn")
    @ResponseBody
    public AjaxResult addColumn(@RequestParam Map param) throws Exception {

        try {
            if (StringUtils.isEmpty(String.valueOf(param.get("tableName")))) {
                return AjaxResult.error("表明不存在");
            }
            //修改参数
            int i = dbService.addColumn(param);
            return toAjax(i);
        }catch (Exception e){
            return AjaxResult.error("更改失败"+e.getMessage());
        }
    }










}
